import java.util.ArrayList;
/**
 * Classe que representa uma composição ferroviária.
 * Uma composição é um conjunto de locomotiva(s) e
 * vagões conectados para para fazer uma viagem.
 *
 */
public class Composicao {

	/**
	 * Variável usada para representar os carros desta composição
	 */
	private ArrayList<Carro> carros;

	/**
	 * Variável usada para armazenar o código
	 */
	private String codigo;

	/* Inicializar variáveis internas */
	public Composicao(String codigo) {
		this.codigo = codigo;
		carros = new ArrayList<Carro>();
	}

	/* Retornar tamanho da composição */
	public int tamanhoComposicao() {
		return carros.size();
	}

	/* Retornar carro na posição indicada */
	public Carro getCarro(int carro) {
		return this.carros.get(carro);
	}

	/*  Adicionar um carro na composição (usar atributos "carros")
	 * - Se carro for locomotiva, inserir no início (posição 0) e dar um shift no restante do vetor
	 * - Senão, inserir no final
	 */
	public void adicionaCarro(Carro carro) {
		/***************************************************************************************************************************************************************************************/
		/**************************************************carro é do tipo Locomotiva**********************************************************************************************************/
		/***************************************************************************************************************************************************************************************/
		if(carro instanceof Locomotiva){
			///////////////////////////////////////////////////////////////////////////////////////Composição vazia/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/////////////////////////////////////////////////////////////////////: locomotiva é o primeiro carro adicionado:///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			if(carros.isEmpty()) {
				//carros.ensureCapacity(carros.size());//capacidade é N-1, agora pode caber N
				carros.add(carro);//locomotiva na primeira posição
			}
			///////////////////////////////////////////////////////////////////////////////////////Composição não vazia/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			///////////////////////////////////////////////////// dar um shift em todos os carros da composição e adicionar a locomotiva na primeira posição////////////////////////////////////////////////////////////////////////////////////////
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			else{
				carros.add(carro);//somente para ganhar uma posição
				/*DESLOCAR OS DEMAIS VAGÕES: APENAS TROCA DAS REFERÊNCIAS*/
				/*MODIFICANDO UM ATRIBUTO*/
				//Nunca tem 1 carro apenas pois foi adicionado a locomotiva sempre tem 2 ou mais!
				for(int i = carros.size(); i >= 2; i--) java.util.Collections.swap(carros, i-1, i-2);//troca os elementos do arraylist anterior vai para posterior
			}//FIM DO TRATAMENTO COMPOSIÇÃO não vazia e carro a inserir é locomotiva
		}
		/****************************************************************************************************************************************************************************************/
		/*******************************************************carro é do tipo Vagão***********************************************************************************************************/
		/***************************************************************************************************************************************************************************************/
		if(carro instanceof VagaoLiquidos ||carro instanceof VagaoGraneleiro) carros.add(carro);//não possui locomotiva sempre na última posição

	}

	/* Retornar true se composição for válida, false caso contrário
	 * Composição é válida se possuir pelo menos uma locomotiva
	 */
	public boolean valida () {
		for(Carro i : carros){
			if(i instanceof Locomotiva) return true;
		}
		return false;	
	}

	/* Retornar soma das capacidades dos vagões de líquidos nesta composição */
	public double capacidadeTotalLiquidos() {
		double capacidadecomposicaoliquidos = 0.0;
		//referencia para realizar downcasting
		VagaoLiquidos j;
		for(Carro i : carros){
			if(i instanceof VagaoLiquidos){
				//downcasting
				j = (VagaoLiquidos)(i); 
				capacidadecomposicaoliquidos= capacidadecomposicaoliquidos+(double)(j.getCapacidade());
			}//fim do if
		}//fim do laço aprimorado
		return capacidadecomposicaoliquidos;
	}//fim do método

	/* retornar soma das capacidades de vagões graneleiros nesta composição */
	public double capacidadeTotalGraneis() {
		double capacidadecomposicaograneis = 0.0;
		//referencia para realizar downcasting
		VagaoGraneleiro j;
		for(Carro i : carros){
			if(i instanceof VagaoGraneleiro){
				//downcasting
				j = (VagaoGraneleiro)(i); 
				capacidadecomposicaograneis=capacidadecomposicaograneis+(double)(j.getCapacidade());
			}//fim do if
		}//fim do laço aprimorado
		return capacidadecomposicaograneis;

	}

	/* retornar true se esta composição é inflamável, false caso contrário
	 * Composição é inflamável se  existir pelo menos um vagão que possa
	 * carregar líquidos inflamáveis
	 */
	public boolean inflamavel () {
		boolean inflamabilidadecomposicao= false;
		//referencia para realizar downcasting
		VagaoLiquidos j;
		//laço aprimorado para percorrer todos os vagões da composição*/
		for(Carro i: carros){
			//analisa apenas os elementos que sejam do tipo VagaoLiquidos
			if(i instanceof VagaoLiquidos){
				j = (VagaoLiquidos)i;
				//se ocorrer um único carro do tipo que seja inflamável toda a composição será
				if(j.inflamavel()) inflamabilidadecomposicao = true;
			}
		}
		return inflamabilidadecomposicao;
	}

	/**
	 * Retorna a representação desta composição como String.
	 */
	public String toString() {
		String retorno = codigo + "|" + capacidadeTotalLiquidos() + "|" +
				capacidadeTotalGraneis() + "|";
		for (Carro carro : carros) {
			retorno = retorno + carro.getCodigo() + "|"; 
		}
		return retorno;
	}
}